﻿using System;
using nRoute.Components;
using nRoute.ViewServices;
using nRoute.Samples.OfficerXcel.ViewServices.Controls;
using nRoute.Components.Handlers;

namespace nRoute.Samples.OfficerXcel.ViewServices.Services
{
    [MapViewService(typeof(IConfirmMessageViewService), 
        Lifetime=ViewServiceLifetime.PerInstance)]
    public class ConfirmationViewService
         : IConfirmMessageViewService
    {
        private ConfirmationWindow _window;
        private DisposableToken _token;
        private Handler<EventArgs, EventHandler> _closeHandler;
        private bool _isConfirmed;

#region IConfirmMessageViewService Members

        public string Title { get; set; }

        public string Message { get; set; }

        /// <returns>Returns a IDisposable based token that can be called to 
        /// cancel the confirmation by closing the window before the user does.</returns>
        public IDisposable Confirm(Action<bool?> confirmationCallback)
        {

            // get the window
            _window = new ConfirmationWindow(Title, Message);

            // set the token
            _token = new DisposableToken(() =>
            {
                // if it has still not been confirmed then dispose the handler before
                // it can be called and close the window - plus remove the variables
                if (!_isConfirmed)
                {
                    _closeHandler.Dispose();
                    _window.Close();
                    confirmationCallback = null;
                    _window = null;
                }
            });
            
            // handler for closing the window
            _closeHandler = new Handler<EventArgs, EventHandler>((s, e) =>
            {
                // we get the response and set that it has been confirmed
                var _response = _window.DialogResult;
                _isConfirmed = true;

                // we callback with the response and then dispose the token
                _token.Dispose();
                confirmationCallback(_response);

                // and nullifiy these
                confirmationCallback = null;
                _window = null;
                
            }, (h) => _window.Closed -= h);

            // and attach the handler and show
            _window.Closed += _closeHandler;
            _window.Show();

            // return the token
            return _token;

        }

#endregion

    }
}
